package humynn.engine
{
	import flash.events.Event;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundMixer;
	import flash.media.SoundTransform;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	/**
	 * Manages loading and playing sounds.
	 */
	public class SoundManager
	{
		private static var _sounds:Array;
		
		private static var _loaded:Boolean;
		
		private static var _urlLoader:URLLoader;
		
		public static var completed:Function;
		
		public function SoundManager()
		{
		}
		
		/**
		 * Checks if all of the sounds are loaded.
		 * 
		 * @returns True if the sounds are loaded, false otherwise.
		 */
		public static function get loaded():Boolean
		{
			return _loaded;
		}
		
		/**
		 * Begins the preloading of the sounds listed in sounds.txt.
		 */
		public static function beginPreload():void
		{
			_loaded = false;
			
			_sounds = new Array();
			
			_urlLoader = new URLLoader();
			_urlLoader.addEventListener(Event.COMPLETE, infoLoaded);
			
			_urlLoader.load(new URLRequest("data/sounds.txt"));
		}
		
		/**
		 * Reads the list of sound files and begins to load them.
		 * 
		 * @param e Ignored.
		 */
		private static function infoLoaded(e:Event):void
		{
			var lines:Array = String(_urlLoader.data).split("\r\n");
			
			for each(var line:String in lines)
			{
				var sound:Array = new Array();
				
				sound.push(line);
				sound.push(new Sound(new URLRequest("data/" + line)));
				
				_sounds.push(sound);
			}
			
			_loaded = true;
			if(completed != null)
			{
				completed();
			}
		}
		
		/**
		 * Plays a sound file.
		 * 
		 * @param file The file name of the sound to play.
		 * @param loop Should the sound be looped.
		 * 
		 * @returns The SoundChannel so that the sound can be controlled.
		 */
		public static function play(file:String, loop:Boolean = false):SoundChannel
		{
			var index:int = findSoundIndex(file);
			
			if(index == -1)
			{
				trace("Can't find " + file);
				return null;
			}
			
			var channelItem:Array = new Array();
			
			var loops:int = 0;
			
			if(loop)
			{
				loops = int.MAX_VALUE;
			}
			
			return _sounds[index][1].play(0, loops);
		}
		
		/**
		 * Finds the index of a sound given the file name.
		 * 
		 * @param file The file name to look up.
		 * 
		 * @returns The index of the sound data or -1 if it was not found.
		 */
		private static function findSoundIndex(file:String):int
		{
			for(var i:int = 0; i < _sounds.length; i++)
			{
				if(_sounds[i][0] == file)
				{
					return i;
				}
			}
			
			return -1;
		}
		
		/**
		 * Gets the volume of all sounds.
		 * 
		 * @returns The volume.
		 */
		public static function getGlobalVolume():uint
		{
			return 100 * SoundMixer.soundTransform.volume;
		}
		
		/**
		 * Sets the volume of all sounds.
		 * 
		 * @param vol The new volume.
		 */
		public static function setGobalVolume(vol:uint):void
		{
			SoundMixer.soundTransform = new SoundTransform(vol/100);
		}
	}
}